package com.github.hiling.common.utils;

import com.github.hiling.common.filter.RequestWrapper;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class RequestUtils {

    public static String getRequestData(HttpServletRequest request, String key) {
        String value = request.getHeader(key);
        if (!org.springframework.util.StringUtils.hasText(value)) {
            value = request.getParameter(key);
        }
        return value;
    }

    /**
     * 获取请求URL
     *
     * @param request 请求
     * @return 示例： GET /api/test?=1
     */
    public static String getRequestUrl(HttpServletRequest request) {
        return String.format("%s %s%s", request.getMethod(), request.getRequestURI(),
                request.getQueryString() == null ? "" : "?" + request.getQueryString());
    }

    public static String getRequestInfo(HttpServletRequest request) {
        return getRequestInfo(request, false);
    }

    /**
     * 获取日志打印时所用的request url
     *
     * @param request            请求
     * @param includeRequestBody 是否包含body
     * @return 请求相关信息，包含keys、body、IP等
     */
    public static String getRequestInfo(HttpServletRequest request, boolean includeRequestBody) {
        StringBuilder sb = new StringBuilder();
        sb.append(System.lineSeparator())
                .append("-----------------------------------------")
                .append(System.lineSeparator());

        sb.append(getRequestUrl(request)).append(System.lineSeparator());

        String token = getRequestData(request, "jwtToken");
        if (StringUtils.hasText(token)) {
            sb.append("jwtToken: ").append(token).append(System.lineSeparator());
        }

        String body = null;
        if (includeRequestBody) {
            if (request instanceof RequestWrapper) {
                body = new RequestWrapper(request).getBody();
            } else if (!org.apache.commons.lang3.StringUtils.isEmpty(request.getContentType()) &&
                    request.getContentType().toLowerCase().contains(MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
                // 如果 contentType = x-www-form-urlencoded时，容器会将body体解析为parameters
                body = getUrlParameter(request.getParameterMap());
            }
        }

        if (org.apache.commons.lang3.StringUtils.isNotEmpty(body)) {
            sb.append("body: ").append(body).append(System.lineSeparator());
        }

        sb.append("IP: ").append(request.getRemoteAddr()).append(System.lineSeparator());
        return sb.toString();
    }

    public static String getUrlParameter(Map<String, String[]> params) {
        return getUrlParameter(params, false);
    }

    public static String getUrlParameter(Map<String, String[]> params, boolean isOrdered) {
        List<String> keys = new ArrayList<>(params.keySet());
        //不按首字母排序, 需要按首字母排序请打开
        if (isOrdered) {
            Collections.sort(keys);
        }
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key)[0];
            value = URLEncoder.encode(value, StandardCharsets.UTF_8);

            // 拼接时，不包括最后一个&字符
            if (i == keys.size() - 1) {
                builder.append(key).append("=").append(value);
            } else {
                builder.append(key).append("=").append(value).append("&");
            }
        }
        return builder.toString();
    }
}
